package org.codeart.singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.springframework.util.SerializationUtils;

/**
 * 枚举方式实现单例
 * 好处  反序列化  安全性高
 */
public enum Singleton06 {

    INSTANCE;

    private Object data;

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public static Singleton06 getInstance() {
        return INSTANCE;
    }

    //    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException,
//            InstantiationException, IllegalAccessException {
    public static void main1(String[] args) throws Exception {
        Singleton06 singleton = Singleton06.INSTANCE;
        Singleton06 instance = singleton.getInstance();
        System.out.println(instance.getData());
//        Class<Singleton06> clazz = Singleton06.class;
//        Constructor<Singleton06> constructor = clazz.getDeclaredConstructor();
//        constructor.setAccessible(true);
//        Singleton06 instance1 = constructor.newInstance();
//        Singleton06 instance2 = constructor.newInstance();
//        System.out.println(instance1 == instance2);

        // 获取枚举实例
        Singleton06 instance1 = Singleton06.INSTANCE;

        // 尝试通过反射创建新实例
        Class<Singleton06> clazz = Singleton06.class;

        // 1. 尝试获取无参构造器 (会失败)
        try {
            Constructor<Singleton06> c1 = clazz.getDeclaredConstructor();
            c1.setAccessible(true);
            c1.newInstance(); // 永远不会执行到这里
        } catch (NoSuchMethodException e) {
            System.out.println("无参构造器获取失败: " + e.getMessage());
        }

        // 2. 尝试获取真实构造器 (会触发JVM保护)
        try {
            Constructor<Singleton06> c2 = clazz.getDeclaredConstructor(
                    String.class,    // 枚举名称
                    int.class       // 枚举序号
            );
            c2.setAccessible(true);

            // 尝试创建新实例 (这里会抛出异常)
            Singleton06 instance2 = c2.newInstance("REFLECT_INSTANCE", 999);
        } catch (InvocationTargetException e) {
            System.out.println("反射创建枚举实例失败: " + e.getCause().getMessage());
        }

        // 验证原始实例仍然有效
        instance1.setData("Hello Enum");
        System.out.println("原始实例数据: " + Singleton06.INSTANCE.getData());
    }

    public static void main2(String[] args) throws Exception {
        Singleton06 s = Singleton06.INSTANCE;

        // 拿到所有的构造函数，包括非public的
        Constructor<Singleton06> constructor = Singleton06.class.getDeclaredConstructor();
        constructor.setAccessible(true);
        // 使用空构造函数new一个实例。即使它是private的~~~
        Singleton06 sReflection = constructor.newInstance();

        System.out.println(s); //com.fsx.bean.Singleton@1f32e575
        System.out.println(sReflection); //com.fsx.bean.Singleton@279f2327
        System.out.println(s == sReflection); // false
    }

    public static void main(String[] args) {
        Singleton06 s = Singleton06.INSTANCE;
        Singleton06 singleton = Singleton06.INSTANCE;
        Singleton06 instance = singleton.getInstance();
        System.out.println(singleton == instance);
        byte[] serialize = SerializationUtils.serialize(s);
        Object deserialize = SerializationUtils.deserialize(serialize);
        System.out.println(s == deserialize); //true
    }
}

